package com.studio49.exmple.common.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.util.StringUtils;

import com.studio49.exmple.common.constant.SysConstant;
import com.studio49.exmple.core.annotation.Validate;

/**
 * 
 * <PRE>
 * 解析注解验证fields
 * </PRE>
 * 
 */
public abstract class ValidateUtils {

	@SuppressWarnings("rawtypes")
	public static void check(Object obj) throws RuntimeException {
		// 获取当前类的属性字段,包括父类的属性字段
		List<Field> fieldList = new ArrayList<Field>();
		Class tempClass = obj.getClass();
		while (tempClass != null && !tempClass.getName().toLowerCase().equals("java.lang.object")) {
			fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
			tempClass = tempClass.getSuperclass();
		}
		for (int i = 0; i < fieldList.size(); i++) {
			Field field = fieldList.get(i);
			// System.out.println(field.getName());
			Object v = getFieldValueByName(field.getName(), obj);
			if (field.isAnnotationPresent(Validate.class)) {
				for (Annotation anno : field.getDeclaredAnnotations()) {
					if (anno.annotationType().equals(Validate.class)) {
						Validate validate = (Validate) anno;
						if (validate.notBlank()) {
							if (v == null) {
								throw new RuntimeException(
										SysConstant.APP_PARAMS_IS_BLANK_CODE + SysConstant.APP_EXCEPTION_DELIMITER
												+ field.getName() + "不能为空，实际的值:" + v + "！");
							}
							if (!StringUtils.isEmpty(validate.paramScope()) && validate.paramScope().contains("~")) {
								String[] split = validate.paramScope().split("~");
								if (v.toString().length() < Integer.parseInt(split[0])
										|| v.toString().length() > Integer.parseInt(split[1])) {
									throw new RuntimeException(SysConstant.APP_PARAMS_SCOPE_CODE
											+ SysConstant.APP_EXCEPTION_DELIMITER + field.getName() + "长度不正确，实际的值:" + v
											+ "有效取值长度:" + validate.paramScope() + "！");
								}
							}
						}
						String[] paramsRange = validate.paramsRange();
						if (paramsRange.length > 0) {
							List<String> paramsRangeList = Arrays.asList(paramsRange);
							if (v != null && !paramsRangeList.contains(v.toString())) {
								throw new RuntimeException(SysConstant.APP_PARAMS_RANGE_CODE
										+ SysConstant.APP_EXCEPTION_DELIMITER + field.getName() + "无效取值，实际取值:" + v
										+ "，有效取值范围:" + Arrays.toString(paramsRange) + "！");
							}
						}
					}
				}
			}
		}
	}

	/**
	 * 使用反射根据属性名称获取属性值
	 * 
	 * @param fieldName
	 *            属性名称
	 * @param o
	 *            操作对象
	 * @return Object 属性值
	 */

	private static Object getFieldValueByName(String fieldName, Object o) {
		try {
			String firstLetter = fieldName.substring(0, 1).toUpperCase();
			String getter = "get" + firstLetter + fieldName.substring(1);
			Method method = o.getClass().getMethod(getter, new Class[] {});
			Object value = method.invoke(o, new Object[] {});
			return value;
		} catch (Exception e) {
			System.out.println("属性不存在");
			return null;
		}
	}
}
